<template>
  <div class="diy-form-designer" ref="wrapperRef">
    <a-layout-header class="diy-header" ref="headerRef">
      <div class="diy-header-left">
        <!-- <Icon icon="i-ant-design:left-outlined" :size="14" /> -->
        <div v-if="isJumpNewPage" class="diy-header-back pr-2" @click="handleBack">
          <span class="ml-5">返回后台</span>
        </div>
        <div class="diy-header-line"></div>
        <div class="ml-2 diy-header-form-name">
          {{ getTitle }}
        </div>
      </div>

      <!-- 中间 -->
      <div class="diy-header-center">
        <Steps
          v-if="stepItems.length > 0"
          v-model:current="currentStepIndex"
          size="small"
          :style="getStepStyle"
          :items="getStepItems"
          @change="handleStepChange"
        />
      </div>

      <!-- 右侧 -->
      <div class="diy-header-right">
        <a-button @click="handlePublish">发布</a-button>
      </div>
    </a-layout-header>
    <a-layout class="diy-main-containe diy-full-container" ref="contentRef" :style="{ height: getContentHeight }">
      <template v-for="item in Object.keys($slots)" :key="item">
        <ScrollContainer
          :style="{ height: getContentHeight + 'px', padding: '5px' }"
          v-show="currentStep.key === item"
          :class="[currentStep.stepClass]"
        >
          <slot :name="item"></slot>
        </ScrollContainer>
      </template>

      <template v-if="currentStep.key === 'form' || stepItems.length == 0">
        <a-layout-sider class="diy-side-panel diy-side h-full" :width="310">
          <WidgetPanel :designer="designer" :scrollerHeight="getContentHeight" />
        </a-layout-sider>

        <a-layout class="diy-center-layout-container">
          <a-layout-header class="diy-toolbar-header" ref="toolbarHeaderRef">
            <ToolbarPanel :designer="designer" />
          </a-layout-header>
          <a-layout-content class="diy-form-widget-content" ref="formWidgetContentRef">
            <FormWidget :scrollerHeight="getFormWidgetHeight" :designer="designer" />
          </a-layout-content>
        </a-layout>

        <a-layout-sider class="diy-form-setting h-full" :width="300">
          <SettingPanel :designer="designer" :scrollerHeight="getContentHeight" />
        </a-layout-sider>
      </template>
    </a-layout>
  </div>
</template>
<script lang="ts" name="diy-form-designer" setup>
  import { ref, unref, toRaw, computed, onMounted, watch, nextTick, PropType } from "vue"
  import ToolbarPanel from "./toolbar-panel/index.vue"
  import { ScrollContainer } from "/@/components/Container"
  import WidgetPanel from "./widget-panel/index.vue"
  import SettingPanel from "./setting-panel/index.vue"
  import FormWidget from "./form-widget/index.vue"
  import { useI18n } from "/@/hooks/web/useI18n"
  import { useGlobSetting } from "/@/hooks/setting"
  import { useMessage } from "/@/hooks/web/useMessage"
  import { cloneDeep, isFunction } from "lodash"
  // import FormFieldList from '/@/views/addon/onlineDev/diyForm/FormFieldList.vue'
  import { useContentHeight } from "/@/hooks/web/useContentHeight"
  import { createDesigner } from "./designer"
  import { Steps, Row, Col } from "ant-design-vue"
  import { useRouter } from "vue-router"
  import { openWindow } from "/@/utils"
  import type { StepItem } from "./type"

  const router = useRouter()
  const currentPagePath = router.currentRoute.value.path
  let id = router.currentRoute.value.query?.id as string

  const currentStepIndex = ref<number>(0)
  const currentStep = ref<any>({})

  const emits = defineEmits(["publish", "heightChange", "update:currentStepKey"])
  const props = defineProps({
    // 是否跳转到新页面
    isJumpNewPage: { type: Boolean, default: true },
    currentStepKey: { type: String, default: null },
    queryApi: { type: Function as PropType<(arg?: any) => any> },
    publishApi: { type: Function as PropType<(arg?: any) => any> },
    stepItems: { type: Array as PropType<StepItem[]>, default: [] },
    stepChange: { type: Function as PropType<(current?: any) => any> },
    stepStyle: {
      type: Object,
      default: () => ({
        width: "280px",
        height: "100%",
      }),
    },
    // designerConfig: {
    //   type: Object,
    //   default: () => {
    //     return {
    //       formTemplates: true,  //是否显示表单模板
    //     }
    //   }
    // },
  })
  // provide('designerConfig', props.designerConfig);

  const designer = ref(createDesigner())
  const { t } = useI18n("")
  const { createMessage, createWarningModal, createConfirm } = useMessage()
  const glob = useGlobSetting()

  const getIsContentFullHeight = computed(() => true)
  const title = ref()
  // title.value
  const getTitle = computed(() => title.value || "表单设计")
  const headerRef = ref()
  const wrapperRef = ref()
  const contentRef = ref()
  const upwardSpace = ref(0)
  const offsetHeightRef = ref(10)
  const toolbarHeaderRef = ref()
  const formWidgetContentRef = ref()

  const getStepStyle = computed(() => ({ ...props.stepStyle, height: "100%" }))

  watch(
    () => props.queryApi,
    async (queryApi: any) => {
      if (id && id !== "" && queryApi && isFunction(queryApi)) {
        const { designerConfig, deleted } = await queryApi(id)
        // 判断是否已经被删除
        if (!deleted && props.isJumpNewPage) {
          createWarningModal({
            title: "数据已被删除",
            centered: false,
            cancelButtonProps: { style: { display: "none" } },
            onOk: () => {
              openWindow(`${currentPagePath}?id=`, { target: "_self" })
            },
            content: `点击确定，重新刷新页面, 发布即创建新数据`,
          })
          return
        }
        designerConfig && designer.value.loadJson(designerConfig)
      }
    },
    {
      deep: true,
      immediate: true,
    }
  )

  watch(
    () => props.currentStepKey,
    (currentStepKey: string) => {
      if (currentStepKey) {
        currentStepIndex.value = props.stepItems.findIndex((e) => e.key === currentStepKey)
      }
    }
  )

  const getStepItems = computed(() => {
    const { stepItems } = props
    stepItems.forEach((e) => (e.status = "wait"))
    const item = stepItems[currentStepIndex.value]
    if (item) {
      currentStep.value = item
      item.status = "process"
    }
    return stepItems
  })

  // 整体内容高度, 包含左侧 + 中 + 右侧
  const { redoHeight, contentHeight } = useContentHeight(getIsContentFullHeight, wrapperRef, [headerRef], [contentRef], upwardSpace, offsetHeightRef)

  // 表单装饰器高度
  const { redoHeight: redoHeightForForm, contentHeight: formWidgetHeight } = useContentHeight(
    getIsContentFullHeight,
    wrapperRef,
    [headerRef, toolbarHeaderRef],
    [contentRef, formWidgetContentRef],
    upwardSpace,
    offsetHeightRef
  )

  const getContentHeight = computed(() => contentHeight.value || 800)
  const getFormWidgetHeight = computed(() => unref(formWidgetHeight) || 800)

  watch(
    () => currentStepIndex.value,
    (val: any) => {
      nextTick(() => {
        redoHeightForForm()
        redoHeight()
      })
    }
  )

  watch(
    () => contentHeight.value,
    (val: Number) => {
      emits("heightChange", getContentHeight)
    }
  )

  onMounted(() => {})

  const handleBack = () => {
    createConfirm({
      title: "警告",
      content: `关闭后所有未保存的数据将会清空，请谨慎操作！`,
      iconType: "warning",
      onOk: () => {},
    })
  }

  const handlePublish = async () => {
    const data = designer.value.genExportJson(false)
    const { publishApi } = props
    if (publishApi && isFunction(publishApi)) {
      try {
        const res = await publishApi(data)
        if (res === false) {
          return
        }
        createMessage.success("发布成功")
      } catch (error) {
        console.error(error)
        createMessage.error("发布失败")
      }
    } else {
      emits("publish", data)
    }
  }

  const handleStepChange = (current) => {
    const step = props.stepItems[current]
    console.log("currentStep", step)
    emits("update:currentStepKey", step.key)
    props.stepChange && props.stepChange(step)
  }

  const setTitle = (v) => (title.value = v)

  defineExpose({
    setTitle,
  })
</script>

<style lang="less">
  @import "./index.less";
</style>
